﻿using System;
using System.Text;
using System.Collections.Generic;
using System.ComponentModel;
using System.Linq;
using Microsoft.VisualStudio.TestTools.UnitTesting;

using MVPlan.Engine;
using MVPlan.Engine.Dive;
using MVPlan.Engine.Gases;
using MVPlan.Engine.Modeling;
using MVPlan.Engine.Segment;

namespace MVPlan.UnitTest
{
    /// <summary>
    /// Summary description for ProfileTest
    /// </summary>
    [TestClass]
    public class ProfileTest
    {
        public ProfileTest()
        {
            //
            // TODO: Add constructor logic here
            //
        }

        private TestContext testContextInstance;

        /// <summary>
        ///Gets or sets the test context which provides
        ///information about and functionality for the current test run.
        ///</summary>
        public TestContext TestContext
        {
            get
            {
                return testContextInstance;
            }
            set
            {
                testContextInstance = value;
            }
        }

        #region Additional test attributes
        //
        // You can use the following additional attributes as you write your tests:
        //
        // Use ClassInitialize to run code before running the first test in the class
        // [ClassInitialize()]
        // public static void MyClassInitialize(TestContext testContext) { }
        //
        // Use ClassCleanup to run code after all tests in a class have run
        // [ClassCleanup()]
        // public static void MyClassCleanup() { }
        //
        // Use TestInitialize to run code before running each test 
        // [TestInitialize()]
        // public void MyTestInitialize() { }
        //
        // Use TestCleanup to run code after each test has run
        // [TestCleanup()]
        // public void MyTestCleanup() { }
        //
        #endregion

        private void setPrefs()
        {
            Prefs.Current.RMVDeco = 12;
            Prefs.Current.RMVDive = 17;
            Prefs.Current.GfLow = 0.3;
            Prefs.Current.GfHigh = 0.8;
            Prefs.Current.AscentRate = -10;
            Prefs.Current.DescentRate = 20;
            Prefs.Current.StopDepthIncrement = 3;
            Prefs.Current.LastStopDepth = 6;
            Prefs.Current.StopTimeIncrement = 1;
            Prefs.Current.Units = Units.Metric;
        }


        [TestMethod]
        public void GasCheck()
        {
            List<Gas> gases = new List<Gas>();
            List<SegmentDive> segments = new List<SegmentDive>();

            setPrefs();

            gases.Add(new Gas(0.21, 0));
            //gases.Add(new Gas(0.21, 0.35));
            //gases.Add(new Gas(0.6, 0));

            segments.Add(new SegmentDive(50, 20, gases[0], 1.3));

            Profile p = new Profile(segments, gases, null);

            p.IsOCDeco = true;

            if (p.DoDive() == ProfileStatus.Success)
            {
                p.DoGasCalcs();
                double used = gases[0].Volume;

                double rt = p.RunTime;

                
            }
            else
            {
                Assert.Fail("Profile.DoDive() != Success");
            }
        }

        [TestMethod]
        public void ProfileCheck()
        {
            List<Gas> gases = new List<Gas>();
            List<SegmentDive> segments = new List<SegmentDive>();

            setPrefs();

            gases.Add(new Gas(0.21, 0));

            segments.Add(new SegmentDive(50, 20, gases[0], 1.3));

            Profile p = new Profile(segments, gases, null);

            p.IsOCDeco = false;

            if (p.DoDive() == ProfileStatus.Success)
            {
                Assert.AreEqual<double>(38, p.RunTime, "Runtime Error.");
                Assert.AreEqual<double>(0.3, p.Model.Gradient.GfLow, "GfLow Error.");
                Assert.AreEqual<double>(0.8, p.Model.Gradient.GfHigh, "GfHigh Error.");
                Assert.AreEqual<Units>(Units.Metric, p.Model.Units, "Units Error.");
                Assert.AreEqual<double>(56.219051498918517, p.Model.OxTox.Otu, "Otu Error.");
                Assert.AreEqual<double>(0.21111111111111119, p.Model.OxTox.Cns, "Cns Error.");
            }
            else
            {
                Assert.Fail("Profile.DoDive()-ccr != Success");
            } 
            
            p.Reset();

            p.IsOCDeco = true;

            if (p.DoDive() == ProfileStatus.Success)
            {
                Console.Write(p.ToString());
                Assert.AreEqual<double>(68, p.RunTime, "Runtime Error.");
                Assert.AreEqual<double>(0.3, p.Model.Gradient.GfLow, "GfLow Error.");
                Assert.AreEqual<double>(0.8, p.Model.Gradient.GfHigh, "GfHigh Error.");
                Assert.AreEqual<Units>(Units.Metric, p.Model.Units, "Units Error.");
                Assert.AreEqual<double>(32.846674842098651, p.Model.OxTox.Otu, "Otu Error.");
                Assert.AreEqual<double>(0.12711883876357558, p.Model.OxTox.Cns, "Cns Error.");
            }
            else
            {
                Assert.Fail("Profile.DoDive()-oc != Success");
            }

        }
    }
}
